<template>
  <div>
    <!-- 头部 -->
    <van-nav-bar fixed>
      <template #left>
        <!-- 文件路径选择 -->
        <!-- .代表文件所在文件夹(home文件夹) -->
        <!-- ..上一级(views文件夹) -->
        <!-- ../..上一级的上一级(src文件夹) -->
        <!-- <img src="../../assets/logo.png" class="logo"> -->
        <img :src="logoImg" class="logo" />
      </template>
      <template #right>
        <!-- postcss只负责css代码,转换不了html size属性值 所以需要换成rem-->
        <van-icon
        name="search"
        size="0.48rem"
        color="white"
        @click="$router.push({path:'/search'})"
         />
      </template>
    </van-nav-bar>

    <!-- 频道 -->
    <div class="content">
      <van-tabs
        @click="toggle"
        v-model="active"
        animated
        sticky
        offset-top="1.22666667rem"
      >
        <!-- 每次循环都是独立执行,所以运行后,这段代码会产生多个 -->
        <van-tab
          :name="item.id"
          v-for="item in channelsList"
          :key="item.id"
          :title="item.name"
        >
        <!-- 文章列表 -->
          <!-- 顶部刷新 -->
          <van-pull-refresh v-model="isLoading" @refresh="onRefresh">
            <!--底部加载更多 list组件控制分页 -->
            <van-list
              v-model="loading"
              :finished="finished"
              finished-text="没有更多了"
              @load="onLoad"
              offset="20"
            >
              <ArticleList :arr="articlesList" @delFn="delFn"></ArticleList>
            </van-list>
          </van-pull-refresh>
        </van-tab>
      </van-tabs>
    </div>
    <!-- 频道右侧加号图标 -->
    <van-icon
      name="plus"
      class="moreChannels"
      size="0.37333334rem"
      @click="show = !show"
    />
    <!-- 频道管理弹出层 -->
    <van-popup
    v-model="show"
     class="edit_wrap"
     @close="$refs.edit.show=false"
    >
      <ChannelEdit
      @colseFN="show = false"
      :userChannelsList="channelsList"
      ref="edit"
      @goChannelFn="goChannelFn"
      />
    </van-popup>
  </div>
</template>

<script>
// 导入图片模块  webpack会把一切都认为是模块(包括图片文件/字体文件...)
import logoImg from '@/assets/logo.png'

// 按需导入 请求接口
import {
  userChannelListAPI,
  articlesListAPI,
  disLikesAPI,
  reportsAPI
} from '@/api'

// 导入文章列表组件
import ArticleList from './components/ArticleList'
import ChannelEdit from './components/ChannelEdit'
// 导入时间处理函数
import { toTimeAgo } from '@/utils/date'
// 自己封装的通知插件
import { MyNotify } from '@/utils/Notify'
// 定义一个存储频道列表的变量
const channelsObj = {} // 数据层面的缓存对象(网页重新打开,重新请求)
export default {
  data () {
    return {
      logoImg: logoImg, // logo图片
      active: 0, // 默认频道中
      channelsList: [], // 频道列表
      channelId: 0, // 频道ID(默认0就是推荐频道)
      articlesList: [], // 文章列表
      loading: false, // 底部加载状态
      finished: false, // 底部加载是否全部
      timestamp: null, // 下一页第一条数据
      isLoading: false, // 顶部加载状态
      show: false // 频道管理弹出层状态
    }
  },
  //   初始化完成发生请求
  async created () {
    //   发送请求-获取频道列表
    const res = await userChannelListAPI()
    this.channelsList = res.data.data.channels

    this.getArticlesList() // 网页打开的时候先请求一次文章列表
  },
  methods: {
    toTimeAgo,
    // 封装文章列表请求
    async getArticlesList () {
      /*
    ?. 叫做可选链操作符
      作用: 防止null或undefined访问里面属性
      例如: cacheObj[this.channelId] 对象里无频道id原地是undefined, 防止往后.arr访问(防止报错)
       cacheObj[this.channelId] ? cacheObj[this.channelId].arr : undefined (等价)
       cacheObj[this.channelId] && cacheObj[this.channelId].arr
       0 && 6  原地就是0
       5 && 9  原地就是9
       兼容: webpack+babel (babel会对ES10的?.的语法降级)

*/

      // 如果切换频道时,channelsObj里面有对应频道id对应的数组,从变量缓存里取值,取到了直接用
      // 下拉加载时,channelsObj里面有对应频道id对应的数组,loading状态为false时才有if分支,否则走else分支
      if (channelsObj[this.channelId]?.arr && this.loading === false) {
        //   赋予这个频道数据,就不用发请求了
        this.articlesList = channelsObj[this.channelId].arr
        // 因为上面数据改变-页面DOM更新异步的  回到之前的位置
        this.$nextTick(() => {
          window.scrollTo(0, channelsObj[this.channelId] ? channelsObj[this.channelId].top : 0)
        })
      } else { // 没找到频道id对应的数组,去请求并缓存
        //   发送请求-获取文章列表
        const res2 = await articlesListAPI({
          channelId: this.channelId,
          timestamp: this.timestamp
        })

        // 底部加载数据全部加载完成
        if (res2.data.data.results.length === 0) {
          this.finished = true
          return // 阻值代码继续向下
        }

        // 时间处理
        res2.data.data.results.forEach((obj) => {
          obj.pubdate = this.toTimeAgo(obj.pubdate)
        })

        // 把下一页的数据和之前的数据合起来
        this.articlesList = [...this.articlesList, ...res2.data.data.results]

        // 因为上来是一个空对象,先定义一个channelsObj下的频道id的空对象
        channelsObj[this.channelId] = {}

        // 页面数据缓存到channelsObj下的频道id的空对象
        channelsObj[this.channelId].arr = this.articlesList

        channelsObj[this.channelId].nextTime = res2.data.data.pre_timestamp
        // 请求下一页的参数,把第上一次请求的参数保存
        this.timestamp = res2.data.data.pre_timestamp

        // 请求下一页的参数缓存到channelsObj下的频道id的空对象
        channelsObj[this.channelId].nextTime = res2.data.data.pre_timestamp
      }

      // 底部加载完成
      this.loading = false

      // 顶部加载完成
      this.isLoading = false
    },

    // 点击切换频道切换数据
    toggle (channelId) {
      // 保存本页已滚动的距离
      channelsObj[this.channelId].top = window.scrollY
      this.channelId = channelId // 把获取到的id保存到data变量上
      // 切换频道, 应该让数组清空/页码回到第一页
      // this.timestamp = null // 请求第一页的数据

      // 当前频道的下一页id
      this.timestamp = channelsObj[this.channelId]?.nextTime // 因为切换下一个页面是还没有,所以先判断一下
      this.articlesList = [] // 把原来的数据清空
      this.getArticlesList() // 根据ID请求改频道的数据
    },

    // 底部加载更多
    onLoad () {
      // 页面一加载,onload会认为已经触底,会发送一次请求,和created里的请求重合,所以如果没有列表的时候,直接return
      if (this.articlesList.length === 0) {
        return
      }
      this.getArticlesList()
    },

    // 顶部刷新
    onRefresh () {
      this.timestamp = null // 请求第一页的数据
      channelsObj[this.channelId].nextTime = null // 把缓存里的下一页页码置空
      channelsObj[this.channelId].arr = null // 把缓存数据也清空
      this.articlesList = [] // 把原来的数据清空
      this.getArticlesList() // 再次发起文章请求
    },
    // 反馈请求
    async delFn (item, action) {
      // 本地列表删除
      const index = this.articlesList.findIndex(
        (obj) => obj.art_id === item.art_id
      )
      if (index !== -1) {
        this.articlesList.splice(index, 1)
      }
      // 后台列表删除
      if (action.name === '不感兴趣') {
        const res = await disLikesAPI({ target: item.art_id })
        console.log(res)
        MyNotify({ type: 'success', message: '不感兴趣成功' })
      } else {
        // 二级面板反馈
        const res = await reportsAPI({
          target: item.art_id,
          type: action.value

        })
        MyNotify({ type: 'success', message: '反馈成功' })
        console.log(res)
      }
    },
    goChannelFn (obj) {
      this.active = obj.id
      this.toggle(this.active)
    }
  },
  components: {
    ArticleList,
    ChannelEdit
  },
  // 组件离开之前,保存当前组件的滚动位置到路由信息对象的meta里
  beforeRouteLeave (to, from, next) {
    //   window.scrollY 返回文档在垂直方向已滚动的像素值
    from.meta.top = window.scrollY
    next()
  },
  //  组件切入后,把他滚动到之前的位置
  activated () {
    //   dom更新后
    this.$nextTick(() => {
      if (this.$route.meta.isScoll) {
        console.log(this.$route.meta.top)
        //  window.scrollTo 滚动到文档中的某个坐标,第一个参数是文档中的横轴坐标,第二个参数是文档中的纵轴坐标。
        window.scrollTo(0, this.$route.meta.top)
      }
    })
  }

}
</script>

<style lang="less" scoped>
.logo {
  width: 100px;
  height: 30px;
}
.content {
  padding-top: 46px;
}
// 设置 tabs 容器的样式
/deep/ .van-tabs__wrap {
  padding-right: 30px;
  background-color: #fff;
}

// 设置小图标的样式
.moreChannels {
  position: fixed;
  top: 60px;
  right: 8px;
  z-index: 999;
}
// 弹出层容器宽度高度铺满屏幕
/*频道编辑弹出层 */
.edit_wrap{
  width: 100%;
  height: 100%;
}
</style>
